<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>Vue的例子1</title>
    <style>
        #app-1 ul>li{
            padding: 20px;
            border-bottom: 1px solid grey;
        }
        .inOn{
            background-color: aqua;
        }
    </style>
</head>
<body>
<div id="app-1">
    {{message}}
    <ul>
        <li>{/{/}/}:双花括号支持javascript表达式、支持变量。但是只能包含单个表达式，不支持预计，控制流。</li>
        <li>directive（指令）是带有v-前缀的特殊属性。指令属性的值预期是单一Javascript表达式，除了v-for。 <br/>
            一些指令可以接受一个“参数”，再指令后面以冒号指明。如：v-bind:href   v-on:click <br/>
            “修饰符”：是以半角句号‘.’指明的特殊后缀。 v-on:submit.prevent='onSubmit'
        </li>
        <li>过滤器：从Vue 2.*开始，只能用在mustache插值和v-bind表达式。添加在javascript表达式的尾部，有“管道”符提示。“复杂的数据变换”，请使用“计算属性” <br/>
            {{newMsg | capitalize}}
        </li>
        <li>缩写：常用的两个指令有缩写。v-bind:title--> :title     v-on:click----> @click</li>
        <li>v-bind：绑定DOM元素属性！
            <div v-bind:title="message">鼠标悬停几秒查看该元素的title提示信息！</div>
        </li>
        <li>v-if：条件与循环 <br/>
            v-on:click :监控事件 比如：click时间，后面可以调用方法以及表达式 <br/>
            v-for:绑定数组数据渲染项目列表
            <div>
                <button v-on:click="seen=!seen">显示或隐藏内容</button>
                <div v-if="seen">参与者列表：
                    <ol v-for="one in viewer">
                        <li>{{one.name}}</li>
                    </ol>
                </div>
            </div>
        </li>
        <li>v-model:实现表单输入和应用状态之间的双向绑定。因为“花括号不能再属性中使用”<br/>
            <input type="text" v-model="inputCont"/>
            <div>输入的内容：{{inputCont}}</div>
        </li>
        <li>v-once:执行一次性插值，当数据在改变是，值不会再改变。
            <p v-once>{{inputCont}}</p>
        </li>
        <li>v-html:花括号会将数据解释为纯文本，而不是HTML。简单的html可以用该指令，复杂的请使用组件component
            <p v-html="rawHtml"></p>
            <p>{{rawHtml}}</p>
        </li>
        <li>计算属性.实例：将变量值颠倒：{{message}} <br/>
            {{reverseMsg}}
            <br/>再javascript中访问Vue的这些属性变量时，比如：myApp.message
        </li>
        <li>methods：更改data变量：{{showMsg()}}-->{{message}}</li>
        <li style="background: pink">
            methods 和 计算属性 相比较，计算属性更加具有优势，计算属性是基于他们的依赖进行缓存的。计算属性只有在相关依赖发生改变时，才会重新求值。这就意味着，只要message不发生变化，多次请求调用计算属性，会立即返回结果，而不必再执行。有缓存。“method”只要发生了重新渲染，就会执行函数。
        </li>
        <li>watch:Vue提供的一种更通用的方式，用来观察和响应Vue实例上的数据变化。 然而，更好的想法是使用computed而不是命令式的watch回调。
            <br/>但是，watch有个好处：当我们再执行异步操作时，能限制我们的操作频率，并在得到最终输入结果时可以设置中间状态。<strong>当你想要在数据变化响应时，执行异步操作或开销较大的操作，这是很有用的。还可以使用：myApp.$watch</strong>
        </li>
        <li>ng-bind:class绑定html的class样式。动态的，静态的。<br/>
            <div v-bind:class="{inOn:isActive}" v-on:click="isActive=!isActive">文本内容</div>
        </li>

    </ul>

    <hr/>

    <div class="component">
        <div>Vue中的组件本质上是一个拥有预定义选项的Vue实例。我们将构建一个组件化的应用系统，组件系统是Vue的一个重要概念，因为它是一个抽象。一个大的应用可以抽象为一个组件树。</div>
        <ol>
            <todo-list v-for="item in items" v-bind:todo="item"></todo-list>
        </ol>
    </div>

    <hr/>
    <div class="instance">
        <p>Vue.js应用都是通过构造函数Vue创建Vue的根实例启动的。new Vue() <br/>
            可以扩展Vue构造器，从而用于定义选项创建可以服用的组件构造器。Vue.extend()
        </p>
    </div>
</div>
<!--<script src="https://unpkg.com/vue/dist/vue.js"></script>-->
<script src="./vue.js"></script>
<script>
    /*组件必须先定义才能正常使用*/
    Vue.component('todo-list',{
//       /*为这个组件添加一个自定义属性,属性名为todo*/
        props:['todo'],
        template:'<li>{{todo.name}}</li>'
    });
    var myApp=new Vue({
        el:'#app-1',
        data:{
            message:'Hello Vue',
            seen:false,
            viewer:[
                {name:"Kate"},
                {name:"Jane"},
                {name:"David"},
                {name:"Ken"}
            ],
            inputCont:'请输入',
            items:[
                {name:'New York'},
                {name:'Tokyo'},
                {name:'Australia'}
            ],
            rawHtml:'<span>这里插入一个html文本</span>',
            newMsg:'hello world',
            isActive:true
        },
        methods:{
            showMsg: function () {
                this.message='Hello method';
            }
        },
        filters:{
            capitalize: function (value) {
                if(!value) return '';
                value=value.toString();
                return value.charAt(0).toUpperCase()+value.slice(1);
            }
        },
        computed:{/*计算属性：用来计算复杂的逻辑*/
            /*getter*/
            reverseMsg: function () {
                return this.message.split('').reverse().join('');
            },
            doMessage:{
                /*getter*/
                get: function () {
                    return this.message;
                },
                /*setter 计算属性默认只有getter，可以自定义setter*/
                set: function (val) {
                    this.message=val;
                }
            }
        }
    });

    console.log(myApp.reverseMsg);
    myApp.message='Hello luofang';
    console.log(myApp.reverseMsg);
</script>
</body>
</html>